#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Basic Safe Handle Class
 *      Provides a basic safe handle implementation.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"
#include "SocketsIncludes.h"

using namespace System;
using namespace System::Runtime;
using namespace System::Runtime::InteropServices;
using namespace System::Net;
using namespace System::Net::Sockets;

namespace Adaptive
{
	namespace Network
	{
		namespace Sockets
		{
			/// <summary>
			/// Provides a basic safe handle implementation.
			/// </summary>
			public ref class Win32Socket sealed
			{
			public:
				/*--------------------------------------------------------------------------------
				 * Public Methods / Functions
				 *------------------------------------------------------------------------------*/
				#pragma region Public Methods / Functions
				/// <summary>
				/// Initializes the Winsock 2 system for use.
				/// </summary>
				/// <remarks>
				/// This method is required before sockets operations may begin; only one call is needed.
				/// </remarks>
				static void InitializeWinsock();
				/// <summary>
				/// De-initializes the Winsock 2 system for use.
				/// </summary>
				/// <remarks>
				/// This method should be the last item called when the application is completed.
				/// </remarks>
				static void ShutdownWinsock();
				/// <summary>
				/// Permits an incoming connection attempt on a socket.
				/// </summary>
				/// <remarks>
				/// The <b>Accept</b> function extracts the first connection on the queue of pending connections on socket 
				/// <i>listeningSocket</i>. It then creates and returns a handle to the new socket. The newly created 
				/// socket is the socket that will handle the actual connection; it has the same properties as socket 
				/// <i>listeningSocket</i> including the asynchronous events registered with the WSAAsyncSelect or 
				/// WSAEventSelect functions.
				///
				/// The <b>Accept</b> function can block the caller until a connection is present if no pending connections are 
				/// present on the queue, and the socket is marked as blocking.
				/// </remarks>
				/// <param name="listeningSocket">A <see cref="SafeSocketHandle"/> containing the handle to the listening socket.</param>
				/// <returns>
				/// The newly created socket handle, if successful; otherwise, returns an invalid instance of <see cref="SafeSocketHandle"/>.
				/// </returns>
				static SafeSocketHandle^	Accept(SafeSocketHandle^ listeningSocket);
				/// <summary>
				/// Permits an incoming connection attempt on a socket.
				/// </summary>
				/// <remarks>
				/// The <b>Accept</b> function extracts the first connection on the queue of pending connections on socket 
				/// <i>listeningSocket</i>. It then creates and returns a handle to the new socket. The newly created 
				/// socket is the socket that will handle the actual connection; it has the same properties as socket 
				/// <i>listeningSocket</i> including the asynchronous events registered with the WSAAsyncSelect or 
				/// WSAEventSelect functions.
				///
				/// The <b>Accept</b> function can block the caller until a connection is present if no pending connections are 
				/// present on the queue, and the socket is marked as blocking.
				/// </remarks>
				/// <param name="listeningSocket">A <see cref="SafeSocketHandle"/> containing the handle to the listening socket.</param>
				/// <param name="remoteAddress">A <see cref="SocketAddress"/> instance to recieve the remote address of the new connection.</param>
				/// <returns>
				/// The newly created socket handle, if successful; otherwise, returns an invalid instance of <see cref="SafeSocketHandle"/>.
				/// </returns>
				static SafeSocketHandle^	Accept(SafeSocketHandle^ listeningSocket, SocketAddress^ remoteAddress);
				/// <summary>
				/// Associates a local address with a socket.
				/// </summary>
				/// <remarks>
				/// 
				/// </remarks>
				/// <param name="listeningSocket">
				/// A <see cref="SafeSocketHandle"/> instance containing the handle to the socket to be bound.
				/// </param>
				/// <param name="addressToBindTo">
				/// A <see cref="SocketAddress"/> instance containing the address to bind the socket instance to.
				/// </param>
				/// <returns>
				/// <b>true</b> if the bind operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				static bool			Bind(SafeSocketHandle^ listeningSocket, SocketAddress^ addressToBindTo);
				/// <summary>
				/// Associates a local address with a socket.
				/// </summary>
				/// <remarks>
				/// 
				/// </remarks>
				/// <param name="listeningSocket">
				/// A <see cref="SafeSocketHandle"/> instance containing the handle to the socket to be bound.
				/// </param>
				/// <param name="addressToBindTo">
				/// An <see cref="IPAddress"/> instance containing the address to bind the socket instance to.
				/// </param>
				/// <param name="remotePort">
				/// The remote port to connect to.
				/// </param>
				/// <returns>
				/// <b>true</b> if the bind operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				static bool			Bind(SafeSocketHandle^ listeningSocket, IPAddress^ addressToBindTo, short remotePort);
				/// <summary>
				/// Associates all addresses with a socket.
				/// </summary>
				/// <remarks>
				/// 
				/// </remarks>
				/// <param name="listeningSocket">
				/// A <see cref="SafeSocketHandle"/> instance containing the handle to the socket to be bound.
				/// </param>
				/// <param name="remotePort">
				/// The remote port to connect to.
				/// </param>
				/// <returns>
				/// <b>true</b> if the bind operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				static bool			BindToAll(SafeSocketHandle^ listeningSocket, short remotePort);
				/// <summary>
				/// Associates the loopback address with a socket.
				/// </summary>
				/// <remarks>
				/// 
				/// </remarks>
				/// <param name="listeningSocket">
				/// A <see cref="SafeSocketHandle"/> instance containing the handle to the socket to be bound.
				/// </param>
				/// <param name="remotePort">
				/// The remote port to connect to.
				/// </param>
				/// <returns>
				/// <b>true</b> if the bind operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				static bool			BindToLoopbackOnly(SafeSocketHandle^ listeningSocket, short remotePort);
				/// <summary>
				/// Closes the open socket handle.
				/// </summary>
				/// <remarks>
				/// The <b>CloseSocket</b> function closes a socket. Use it to release the socket descriptor <i>socketHandle</i> so 
				/// that further references to <i>socketHandle</i> fail.
				///
				/// An application should not assume that any outstanding I/O operations on a socket will all be 
				/// guaranteed to completed when <b>CloseSocket</b> returns.
				/// </remarks>
				/// <param name="socketHandle">
				/// An <see cref="IntPtr"/> instance containing the handle to be closed.
				/// </param>
				static void		CloseSocket(IntPtr socketHandle);
				/// <summary>
				/// Closes the open socket handle.
				/// </summary>
				/// <remarks>
				/// The <b>CloseSocket</b> function closes a socket. Use it to release the socket descriptor <i>socketHandle</i> so 
				/// that further references to <i>socketHandle</i> fail.
				///
				/// An application should not assume that any outstanding I/O operations on a socket will all be 
				/// guaranteed to completed when <b>CloseSocket</b> returns.
				/// </remarks>
				/// <param name="socketHandle">
				/// A <see cref="SafeSocketHandle"/> instance containing the handle to be closed.
				/// </param>
				static void		CloseSocket(SafeSocketHandle^ socketHandle);
				/// <summary>
				/// Attempts to establish a connection to a remote host.
				/// </summary>
				/// <remarks>
				/// The connect function is used to create a connection to the specified destination. If socket <i>socket</i>, is 
				/// unbound, unique values are assigned to the local association by the system, and the socket is marked 
				/// as bound.
				/// </remarks>
				/// <param name="socket">The <see cref="SafeSocketHandle"/> instance containing the socket handle to connect on.</param>
				/// <param name="remoteAddress">The <see cref="IPAddress"/> instance containing the remote address to connect to.</param>
				/// <param name="remotePort">The Internet port number to connect to.</param>
				/// <returns>
				/// <b>true</b> if the operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				/// <exception cref="SocketException">Thrown if the connect function fails and returns SOCKET_ERROR.</exception>
				static bool		Connect(SafeSocketHandle^ socket, IPAddress^ remoteAddress, short remotePort);
				/// <summary>
				/// Attempts to establish a connection to a remote host.
				/// </summary>
				/// <remarks>
				/// The connect function is used to create a connection to the specified destination. If socket <i>socket</i>, is 
				/// unbound, unique values are assigned to the local association by the system, and the socket is marked 
				/// as bound.
				/// </remarks>
				/// <param name="socket">The <see cref="SafeSocketHandle"/> instance containing the socket handle to connect on.</param>
				/// <param name="remoteAddress">The <see cref="SocketAddress"/> instance containing the remote address to connect to.</param>
				/// <returns>
				/// <b>true</b> if the operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				/// <exception cref="SocketException">Thrown if the connect function fails and returns SOCKET_ERROR.</exception>
				static bool		Connect(SafeSocketHandle^ socket, SocketAddress^ remoteAddress);
				/// <summary>
				/// Attempts to establish a connection to a remote host.
				/// </summary>
				/// <remarks>
				/// The connect function is used to create a connection to the specified destination. If socket <i>socket</i>, is 
				/// unbound, unique values are assigned to the local association by the system, and the socket is marked 
				/// as bound.
				/// </remarks>
				/// <param name="socket">The <see cref="SafeSocketHandle"/> instance containing the socket handle to connect on.</param>
				/// <param name="remoteAddress">The <see cref="IPEndPoint"/> instance containing the remote address to connect to.</param>
				/// <returns>
				/// <b>true</b> if the operation is successful; otherwise, returns <b>false</b>.
				/// </returns>
				/// <exception cref="SocketException">Thrown if the connect function fails and returns SOCKET_ERROR.</exception>
				static bool		Connect(SafeSocketHandle^ socket, IPEndPoint^ remoteAddress);
				/// <summary>
				/// Retrieves the local name for a socket.
				/// </summary>
				/// <remarks>
				/// The <b>GetSocketName</b> function retrieves the current name for the specified socket descriptor in 
				/// <i>socket</i>.  It is used on the bound or connected socket specified by the <i>socket</i> parameter.
				/// </remarks>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> containing the descriptor for the socket.</param>
				/// <returns>
				/// A <see cref="SocketAddress"/> instance that receives the address (name) of the socket.
				/// </returns>
				static SocketAddress^		GetSocketName(SafeSocketHandle^ socket);
				/// <summary>
				/// Retrieves a socket option.
				/// </summary>
				/// <remarks>
				/// The <b>GetSocketOption</b> function retrieves the current value for a socket option associated with a socket of 
				/// any type, in any state, and stores the result in optval. Options can exist at multiple protocol 
				/// levels, but they are always present at the uppermost socket level. Options affect socket operations, 
				/// such as the packet routing and OOB data transfer.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> containing the socket descriptor.
				/// </param>
				/// <param name="name">
				/// A <see cref="SocketOptionName"/> enumerated value indicating the socket option to be retrieved. 
				/// </param>
				/// <returns>
				/// A <see cref="SocketOptionBase"/> instance used to represent and containg the socket option 
				/// level, name, and value for the requested item.
				/// </returns>
				generic<typename T>
				static SocketOptionBase<T>^	GetSocketOption(SafeSocketHandle^ socket, SocketOptionName name);
				/// <summary>
				/// Retrieves a socket option.
				/// </summary>
				/// <remarks>
				/// The <b>GetSocketOption</b> function retrieves the current value for a socket option associated with a socket of 
				/// any type, in any state, and stores the result in optval. Options can exist at multiple protocol 
				/// levels, but they are always present at the uppermost socket level. Options affect socket operations, 
				/// such as the packet routing and OOB data transfer.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the socket.
				/// </param>
				/// <param name="name">
				/// A <see cref="SocketOptionName"/> enumerated value indicating the socket option to be retrieved. 
				/// </param>
				/// <returns>
				/// A <see cref="SocketOptionBase"/> instance used to represent and containg the socket option 
				/// level, name, and value for the requested item.
				/// </returns>
				generic<typename T>
				static SocketOptionBase<T>^	GetSocketOption(Socket^ socket, SocketOptionName name);
				/// <summary>
				/// Sets a socket option.
				/// </summary>
				/// <remarks>
				/// The setsockopt function sets the current value for a socket option associated with a socket of any type, in any state.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> containing the socket descriptor.
				/// </param>
				/// <param name="option">
				/// A <see cref="SocketOptionBase"/> object instance contaning the socket option level and name
				/// values defining the option to be set, and containing the value to be set.
				/// </param>
				generic<typename T>
				static void	SetSocketOption(SafeSocketHandle^ socket, SocketOptionBase<T>^ option);
				/// <summary>
				/// Sets a socket option.
				/// </summary>
				/// <remarks>
				/// The setsockopt function sets the current value for a socket option associated with a socket of any type, in any state.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the socket.
				/// </param>
				/// <param name="option">
				/// A <see cref="SocketOptionBase"/> object instance contaning the socket option level and name
				/// values defining the option to be set, and containing the value to be set.
				/// </param>
				generic<typename T>
				static void	SetSocketOption(Socket^ socket, SocketOptionBase<T>^ option);
				/// <summary>
				/// Places a socket in a state in which it is listening for an incoming connection.
				/// </summary>m
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="backLogSize">The Maximum length of the queue of pending connections.</param>
				/// <returns>
				/// <b>true</b> if the socket successfully enters the listening state; otherwise, <b>false</b>.
				/// </returns>
				static bool	Listen(SafeSocketHandle^ socket, int backLogSize);
				/// <summary>
				/// Places a socket in a state in which it is listening for an incoming connection.
				/// </summary>
				/// <param name="socket">A <see cref="Socket"/> instance containing the socket descriptor.</param>
				/// <param name="backLogSize">The Maximum length of the queue of pending connections.</param>
				/// <returns>
				/// <b>true</b> if the socket successfully enters the listening state; otherwise, <b>false</b>.
				/// </returns>
				static bool	Listen(Socket^ socket, int backLogSize);
				/// <summary>
				/// Receives data from a connected or bound socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// The data read from the socket buffer.
				/// </returns>
				static array<Byte>^	Recieve(SafeSocketHandle^ socket, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// Receives data from a connected or bound socket.
				/// </summary>
				/// <param name="socket">A <see cref="Socket"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// The data read from the socket buffer.
				/// </returns>
				static array<Byte>^	Recieve(Socket^ socket, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// Receives a byte of data from a connected or bound socket.
				/// </summary>
				/// <param name="socket">A <see cref="Socket"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// A byte of data read from the socket buffer.
				/// </returns>
				static Byte	RecieveByte(SafeSocketHandle^ socket, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// Receives a datagram and stores the source address.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFrom">A <see cref="SocketAddress"/> instance that holds the source address.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// The data read from the buffer.
				/// </returns>
				static array<Byte>^	RecieveFrom(SafeSocketHandle^ socket, SocketAddress^ recieveFrom, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// Receives a datagram and stores the source address.
				/// </summary>
				/// <param name="socket">A <see cref="Socket"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFrom">A <see cref="SocketAddress"/> instance that holds the source address.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// The data read from the buffer.
				/// </returns>
				static array<Byte>^	RecieveFrom(Socket^ socket, SocketAddress^ recieveFrom, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// Receives a datagram and stores the source address.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="recieveFrom">An <see cref="IPEndPoint"/> instance that holds the source address.</param>
				/// <param name="recieveFlags">The flags that influence the behavior of this function.</param>
				/// <returns>
				/// The data read from the buffer.
				/// </returns>
				static array<Byte>^	RecieveFrom(Socket^ socket, IPEndPoint^ recieveFrom, SocketRecieveFlags recieveFlags);
				/// <summary>
				/// The <b>Select</b> function determines the status of one or more sockets, waiting if necessary, 
				/// to perform synchronous I/O.
				/// </summary>
				/// <param name="socketsReadList">
				/// An array of <see cref="SafeSocketHandle"/> instances containing the socket handles to be examined for readability.
				/// </param>
				/// <param name="socketsWriteList">
				/// An array of <see cref="SafeSocketHandle"/> instances containing the socket handles to be examined for writability.
				/// </param>
				/// <param name="socketsErrorList">
				/// An array of <see cref="SafeSocketHandle"/> instances containing the socket handles to be examined for errors.
				/// </param>
				/// <param name="timeout">Maximum time for select to wait.</param>
				/// <returns>
				/// The select function returns the total number of socket handles that are ready and contained in
				/// the specified arrays.
				/// </returns>
				static int		Select( array<SafeSocketHandle^>^ socketsReadList, 
								array<SafeSocketHandle^>^ socketsWriteList, 
								array<SafeSocketHandle^>^ socketsErrorList, 
								int timeout);
				/// <summary>
				/// The <b>SelectSocketReadble</b> function determines the readability status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket can be read from; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketReadble(SafeSocketHandle^ socket);
				/// <summary>
				/// The <b>SelectSocketReadble</b> function determines the readability status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket can be read from; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketReadble(Socket^ socket);
				/// <summary>
				/// The <b>SelectSocketWriteable</b> function determines the writability status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket can be written to; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketWriteable(SafeSocketHandle^ socket);
				/// <summary>
				/// The <b>SelectSocketWriteable</b> function determines the writability status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket can be written to; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketWriteable(Socket^ socket);
				/// <summary>
				/// The <b>SelectSocketWriteable</b> function determines the error status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket has errors; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketErrors(SafeSocketHandle^ socket);
				/// <summary>
				/// The <b>SelectSocketWriteable</b> function determines the error status of a specified socket, 
				/// waiting if necessary, to perform synchronous I/O.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the descriptor of the socket to be examined.
				/// </param>
				/// <returns>
				/// <b>true</b> if the specified socket has errors; otherwise, <b>false</b>.
				/// </returns>
				static bool		SelectSocketErrors(Socket^ socket);
				/// <summary>
				/// Sends data on a connected socket.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> instance containing the descriptor of the socket.
				/// </param>
				/// <param name="dataToSend">
				/// An array of bytes containing the data to be sent.
				/// </param>
				/// <param name="sendFlags">
				/// A set of flags that specify the way in which the call is made.
				/// </param>
				/// <returns>
				/// The number of bytes actually transmitted.
				/// </returns>
				static int		Send(SafeSocketHandle^ socket, array<Byte>^ dataToSend, SocketSendFlags sendFlags);
				/// <summary>
				/// Sends data on a connected socket.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the descriptor of the socket.
				/// </param>
				/// <param name="dataToSend">
				/// An array of bytes containing the data to be sent.
				/// </param>
				/// <param name="sendFlags">
				/// A set of flags that specify the way in which the call is made.
				/// </param>
				/// <returns>
				/// The number of bytes actually transmitted.
				/// </returns>
				static int		Send(Socket^ socket, array<Byte>^ dataToSend, SocketSendFlags sendFlags);
				/// <summary>
				/// The <b>ShutdownSocket</b> function disables sends or receives on a socket.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> instance containing the descriptor of the socket.
				/// </param>
				/// <param name="how">Flag that describes what types of operation will no longer be allowed.</param>
				static void	ShutdownSocket(SafeSocketHandle^ socket, SocketShutdown how);
				/// <summary>
				/// The <b>ShutdownSocket</b> function disables sends or receives on a socket.
				/// </summary>
				/// <param name="socket">
				/// A <see cref="Socket"/> instance containing the descriptor of the socket.
				/// </param>
				/// <param name="how">Flag that describes what types of operation will no longer be allowed.</param>
				static void	ShutdownSocket(Socket^ socket, SocketShutdown how);
				/// <summary>
				/// Creates a new socket instance.
				/// </summary>
				/// <param name="addressFamily">
				/// A <see cref="AddressFamily"/> enumerated type indicating the address family specification.
				/// </param>
				/// <param name="socketType">
				/// A <see cref="SocketType"/> enumerated type indicating the type specification for the new socket.
				/// </param>
				/// <param name="protocolType">
				/// A <see cref="ProtocolType"/> enumerated type indicating the The protocol to be used.
				/// </param>
				/// <returns>
				/// A new <see cref="SafeSocketHandle"/> instance containing the new socket if successful;
				/// otherwise, returns <b>null</b>.
				/// </returns>
				static SafeSocketHandle^ InitSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
				/// <summary>
				/// The <b>HostToNetworkOrder</b> function converts an unsigned integer from host to TCP/IP network \
				/// byte order (which is big-endian).
				/// </summary>
				/// <param name="original">The value to be converted.</param>
				/// <returns>
				/// The <i>original</i> value in big-endian format.
				/// </returns>
				static unsigned int HostToNetworkOrder(unsigned int original);
				/// <summary>
				/// The <b>HostToNetworkOrder</b> function converts an unsigned short integer from host to TCP/IP network \
				/// byte order (which is big-endian).
				/// </summary>
				/// <param name="original">The value to be converted.</param>
				/// <returns>
				/// The <i>original</i> value in big-endian format.
				/// </returns>
				static unsigned short HostToNetworkOrder(unsigned short original);
				/// <summary>
				/// The <b>HostToNetworkOrder</b> function converts an unsigned integer from TCP/IP network order to host 
				/// byte order (which is little-endian on Intel processors).
				/// </summary>
				/// <param name="original">The value to be converted.</param>
				/// <returns>
				/// The <i>original</i> value in little-endian format.
				/// </returns>
				static unsigned int NetworkOrderToHost(unsigned int original);
				/// <summary>
				/// The <b>HostToNetworkOrder</b> function converts an unsigned short integer from TCP/IP network order to host 
				/// byte order (which is little-endian on Intel processors).
				/// </summary>
				/// <param name="original">The value to be converted.</param>
				/// <returns>
				/// The <i>original</i> value in little-endian format.
				/// </returns>
				static unsigned short NetworkOrderToHost(unsigned short original);
				/// <summary>
				/// The <b>InetAddr</b> function converts a string containing an (Ipv4) Internet Protocol dotted address into a 
				/// proper address for the IPAddress instance.
				/// </summary>
				/// <param name="original">The string to be converted.</param>
				/// <returns>
				/// An <see cref="IPAddress"/> instance if successful; otherwise, returns <b>null</b>.
				/// </returns>
				static IPAddress^ InetAddr(String^ original);
				/// <summary>
				/// The <b>InetNtoA</b> function converts an (Ipv4) Internet network address into a string in 
				/// Internet standard dotted-decimal format.
				/// </summary>
				/// <param name="addressValue">The address value to be converted.</param>
				/// <returns>
				/// A string containing the dotted notation of the address.
				/// </returns>
				static String^		InetNtoA(unsigned int addressValue);
				/// <summary>
				/// The <b>InetNtoA</b> function converts an (Ipv4) Internet network address into a string in 
				/// Internet standard dotted-decimal format.
				/// </summary>
				/// <param name="addressValue">The <see cref="IPAddress"/> instance containing the address value to be converted.</param>
				/// <returns>
				/// A string containing the dotted notation of the address, or a blank string on failure.
				/// </returns>
				static String^		InetNtoA(IPAddress^ addressValue);
				/// <summary>
				/// The <b>InetNtoA</b> function converts an (Ipv4) Internet network address into a string in 
				/// Internet standard dotted-decimal format.
				/// </summary>
				/// <param name="addressValue">The <see cref="SocketAddress"/> instance containing the address value to be converted.</param>
				/// <returns>
				/// A string containing the dotted notation of the address, or a blank string on failure.
				/// </returns>
				static String^		InetNtoA(SocketAddress^ addressValue);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(SafeSocketHandle^ socket, int command, short argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(SafeSocketHandle^ socket, int command, int argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(SafeSocketHandle^ socket, int command, __int64 argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(SafeSocketHandle^ socket, int command, String^ argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(SafeSocketHandle^ socket, int command, array<Byte>^ argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(Socket^ socket, int command, short argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(Socket^ socket, int command, int argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(Socket^ socket, int command, __int64 argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(Socket^ socket, int command, String^ argumentData);
				/// <summary>
				/// Controls the I/O mode of a socket.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <param name="command">A value indicating the command to perform on the socket.</param>
				/// <param name="argumentData">Argument data.</param>
				/// <returns>
				/// Returns zero(0) if successful; otherwise, returns SOCKET_ERROR.
				/// </returns>
				static int			IoCtlSocket(Socket^ socket, int command, array<Byte>^ argumentData);
				/// <summary>
				/// Gets the number of bytes waiting to be read in a socket's incoming buffer.
				/// </summary>
				/// <param name="socket">A <see cref="SafeSocketHandle"/> instance containing the socket descriptor.</param>
				/// <returns>
				/// The number of bytes waiting to be read.
				/// </returns>
				static int			GetPendingReadByteCount(SafeSocketHandle^ socket);
				/// <summary>
				/// Gets the number of bytes waiting to be read in a socket's incoming buffer.
				/// </summary>
				/// <param name="socket">A <see cref="Socket"/> instance containing the socket descriptor.</param>
				/// <returns>
				/// The number of bytes waiting to be read.
				/// </returns>
				static int			GetPendingReadByteCount(Socket^ socket);
				/// <summary>
				/// Gets the remote host/peer address information for the specified socket instance.
				/// </summary>
				/// <remarks>
				/// This method is used to determine the remote address information for an existing socket
				/// connection.  This wraps the winsock <b>getpeername</b> method.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> containing the unmanaged socket handle.
				/// </param>
				/// <returns>
				/// An <see cref="IPEndPoint"/> containing the address data if successful; otherwise, 
				/// returns <b>null</b>.
				/// </returns>
				static IPEndPoint^	GetRemoteHostAddress(SafeSocketHandle^ socket);
				/// <summary>
				/// Gets the local host/peer address information for the specified socket instance.
				/// </summary>
				/// <remarks>
				/// This method is used to determine the local address information for an existing socket
				/// connection.  This wraps the winsock <b>getsockname</b> method.
				/// </remarks>
				/// <param name="socket">
				/// A <see cref="SafeSocketHandle"/> containing the unmanaged socket handle.
				/// </param>
				/// <returns>
				/// An <see cref="IPEndPoint"/> containing the address data if successful; otherwise, 
				/// returns <b>null</b>.
				/// </returns>
				static IPEndPoint^	GetLocalHostAddress(SafeSocketHandle^ socket);
				#pragma endregion

			private:
				/*--------------------------------------------------------------------------------
				 * Constructor / Dispose / Destructor Methods
				 *------------------------------------------------------------------------------*/
				#pragma region Constructor / Dispose / Destructor Methods
				/// <summary>
				/// Initializes a new instance of the class.
				/// </summary>
				/// <remarks>
				/// This constructor is hidden to prevent instantiation.
				/// </remarks>
				Win32Socket();

				static LPWSADATA wsData = NULL;
				static LPCRITICAL_SECTION lock;

				#pragma endregion

				#pragma region "Static Private Methods"

				static sockaddr*		SockAddrToUnManaged(SocketAddress^ address);
				static SocketAddress^	SockAddrToManaged(sockaddr* address);

				static sockaddr_in*		IpAddrToUnManaged(IPAddress^ address);
				static IPAddress^		IpAddrToManaged(sockaddr_in* address);

				static SOCKET			SocketToUnmanaged(Socket^ originalSocket);
				static SOCKET			SocketToUnmanaged(SafeSocketHandle^ originalSocket);
				static SafeSocketHandle^SocketToManaged(SOCKET originalSocket);

				static FD_SET*			ConvertToFdSetArray(array<SafeSocketHandle^>^ arrayList);
				static array<SafeSocketHandle^>^ ConvertFromFdSetArray(FD_SET* unmanagedArray);
				#pragma endregion
			};
		}
	}
}

